package com.medical.data.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.medical.data.constEnum.CommonEnum;
import com.medical.data.domain.Patient;
import com.medical.data.domain.ProjectData;
import com.medical.data.domain.User;
import com.medical.data.domain.UserPermission;
import com.medical.data.exception.MyException;
import com.medical.data.mapper.UserPermissionMapper;
import com.medical.data.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.medical.data.utils.ResultCode;
import com.medical.data.vo.GetJoinUserVo;
import com.medical.data.vo.JoinUserVo;
import com.medical.data.vo.UserPermissionsVo;
import com.mysql.cj.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author wz
 * @since 2024-05-19
 */
@Service
public class UserPermissionServiceImpl extends ServiceImpl<UserPermissionMapper, UserPermission> implements UserPermissionService {
    @Autowired
    private TokenSerivce tokenSerivce;

    @Autowired
    private ProjectDataService projectDataService;

    @Autowired
    private UserService userService;

    @Autowired
    private DepartmentService departmentService;

    @Autowired
    private HospitalInformationService hospitalInformationService;

    @Override
    public String getOwnUserIdByProjectId(String projectId) {
        LambdaQueryWrapper<UserPermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserPermission::getProjectId, projectId);
        List<UserPermission> userPermissions = this.baseMapper.selectList(wrapper);
        return userPermissions.get(0).getProjectOwnId();
    }

    @Override
    public void joinProject(String projectId) {
        User user = tokenSerivce.getUser();
        //对项目有效性进行检验
        projectDataService.projectValid(projectId);
        //不能重复申请加入项目
        LambdaQueryWrapper<UserPermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserPermission::getProjectId, projectId)
                .eq(UserPermission::getUserId, user.getId())
                .eq(UserPermission::getProjectOwnId, getOwnUserIdByProjectId(projectId));
        Long count = this.baseMapper.selectCount(wrapper);
        if (count > 0) {
            throw new MyException(ResultCode.ERROR.getCode(), "不能重复申请加入项目");
        }
        UserPermission userPermission = new UserPermission();
        userPermission.setProjectId(projectId);
        userPermission.setProjectOwnId(getOwnUserIdByProjectId(projectId));
        userPermission.setUserId(user.getId());
        int insert = this.baseMapper.insert(userPermission);
        if (insert < 1) {
            throw new MyException(ResultCode.ERROR.getCode(), "申请加入项目失败");
        }
    }

    @Override
    public Map<String, Object> getJoinUser(GetJoinUserVo getJoinUserVo) {
        //构造分页查询参数
        Integer currentPage = CommonEnum.OTHER_PATIENT_CURRENT.getValue();
        Integer pageSize = CommonEnum.OTHER_PATIENT_LIMIT.getValue();
        if (!ObjectUtils.isEmpty(getJoinUserVo.getCurrentPage())) {
            currentPage = getJoinUserVo.getCurrentPage();
        }
        if (!ObjectUtils.isEmpty(getJoinUserVo.getPageSize())) {
            pageSize = getJoinUserVo.getPageSize();
        }
        Page<UserPermission> page = new Page<>(currentPage, pageSize);
        Map<String, Object> result = new HashMap<>();
        User user = tokenSerivce.getUser();
        LambdaQueryWrapper<UserPermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserPermission::getProjectId, getJoinUserVo.getProjectId())
                .eq(UserPermission::getProjectOwnId, user.getId())
                .eq(UserPermission::getRealUser, false);
        //执行查询得到page对象,转成list
        IPage<UserPermission> userPermissionsPage = this.baseMapper.selectPage(page, wrapper);
        List<UserPermission> userPermissionsList = userPermissionsPage.getRecords();

        result.put("total", userPermissionsPage.getTotal());
        result.put("currentPage", currentPage);
        result.put("pageSize", pageSize);

        List<User> users = new ArrayList<>();
        List<JoinUserVo> joinUserVos = new ArrayList<>();

        for (UserPermission userPermission : userPermissionsList) {
            if (!StringUtils.isNullOrEmpty(userPermission.getUserId())) {
                User user1 = new User();
                user1 = userService.getUserById(userPermission.getUserId());
                JoinUserVo joinUserVo = new JoinUserVo();
                joinUserVo.setProjectId(getJoinUserVo.getProjectId());
                joinUserVo.setUserId(userPermission.getUserId());
                joinUserVo.setGender(user1.getGender());
                joinUserVo.setUserName(user1.getNickName());
                joinUserVo.setUserPhone(user1.getPhone());
                joinUserVo.setHospitalName(hospitalInformationService.getNameById(user1.getHsId()));
                joinUserVo.setDepartmentName(departmentService.getDepartmentById(user1.getDepartmentId()));
                joinUserVos.add(joinUserVo);
            }
        }

        result.put("result", joinUserVos);
        return result;
    }

    @Override
    public void createOwnUser(String ownId, String projectId) {
        UserPermission userPermission = new UserPermission();
        userPermission.setUserId(ownId);
        userPermission.setRealUser(true);
        userPermission.setProjectOwnId(ownId);
        userPermission.setProjectId(projectId);
        userPermission.setFormPermission(true);
        userPermission.setDataPermission(true);
        userPermission.setFollowUpPermission(true);
        userPermission.setPatientPermission(true);
        userPermission.setAdvicePermission(true);
        int insert = this.baseMapper.insert(userPermission);
        if (insert < 1) {
            throw new MyException(ResultCode.ERROR.getCode(), "给与最高权限失败");
        }
    }

    @Override
    public void agreeUser(String projectId, String userId) {
        User user = tokenSerivce.getUser();
        LambdaUpdateWrapper<UserPermission> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(UserPermission::getProjectId, projectId)
                .eq(UserPermission::getUserId, userId)
                .set(UserPermission::getRealUser, true);
        int update = this.baseMapper.update(null, wrapper);
        if (update < 1) {
            throw new MyException(ResultCode.ERROR.getCode(), "同意用户加入项目失败");
        }
    }

    @Override
    public void removeUser(String projectId, String userId) {
        User user = tokenSerivce.getUser();
        String realUserId = user.getId();
        if (!realUserId.equals(getOwnUserIdByProjectId(projectId))) {
            throw new MyException(ResultCode.ERROR.getCode(), "用户没有移除项目参与者权限");
        }
        LambdaQueryWrapper<UserPermission> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(UserPermission::getProjectId, projectId)
                .eq(UserPermission::getUserId, userId);

        UserPermission userPermission = this.baseMapper.selectOne(wrapper1);
        if (userPermission.getProjectOwnId().equals(userPermission.getUserId())) {
            throw new MyException(ResultCode.ERROR.getCode(), "不能移除项目创建者");
        }
        LambdaUpdateWrapper<UserPermission> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(UserPermission::getProjectId, projectId)
                .eq(UserPermission::getUserId, userId)
                .set(UserPermission::getRealUser, false)
                .set(UserPermission::getAdvicePermission, false)
                .set(UserPermission::getDataPermission, false)
                .set(UserPermission::getFormPermission, false)
                .set(UserPermission::getPatientPermission, false)
                .set(UserPermission::getFollowUpPermission, false);
        int update = this.baseMapper.update(null, wrapper);
        if (update < 1) {
            throw new MyException(ResultCode.ERROR.getCode(), "移除项目参与者失败");
        }
    }

    @Override
    public void assignPermissions(UserPermissionsVo userPermissionsVo) {
        User user = tokenSerivce.getUser();
        String realUserId = user.getId();
        if (!realUserId.equals(getOwnUserIdByProjectId(userPermissionsVo.getProjectId()))) {
            throw new MyException(ResultCode.ERROR.getCode(), "用户没有分配用户权限得权限");
        }
        LambdaUpdateWrapper<UserPermission> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(UserPermission::getUserId, userPermissionsVo.getUserId())
                .eq(UserPermission::getProjectId, userPermissionsVo.getProjectId())
                .eq(UserPermission::getRealUser, true)
                .set(UserPermission::getAdvicePermission, userPermissionsVo.getAdvicePermission())
                .set(UserPermission::getDataPermission, userPermissionsVo.getDataPermission())
                .set(UserPermission::getFormPermission, userPermissionsVo.getFormPermission())
                .set(UserPermission::getPatientPermission, userPermissionsVo.getPatientPermission())
                .set(UserPermission::getFollowUpPermission, userPermissionsVo.getFollowUpPermission());

        int update = this.baseMapper.update(null, wrapper);
        if (update < 1) {
            throw new MyException(ResultCode.ERROR.getCode(), "分配权限失败");
        }
    }

    @Override
    public Map<String, Object> getJoinedProjectUser(GetJoinUserVo getJoinUserVo) {
        //构造分页查询参数
        Integer currentPage = CommonEnum.OTHER_PATIENT_CURRENT.getValue();
        Integer pageSize = CommonEnum.OTHER_PATIENT_LIMIT.getValue();
        if (!ObjectUtils.isEmpty(getJoinUserVo.getCurrentPage())) {
            currentPage = getJoinUserVo.getCurrentPage();
        }
        if (!ObjectUtils.isEmpty(getJoinUserVo.getPageSize())) {
            pageSize = getJoinUserVo.getPageSize();
        }
        Page<UserPermission> page = new Page<>(currentPage, pageSize);
        Map<String, Object> result = new HashMap<>();
        User user = tokenSerivce.getUser();
        LambdaQueryWrapper<UserPermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserPermission::getProjectId, getJoinUserVo.getProjectId())
                .eq(UserPermission::getRealUser, true)
                .eq(UserPermission::getProjectOwnId, user.getId())
                .orderByAsc(UserPermission::getCreateTime);//时间顺序返回

        //执行查询得到page对象,转成list
        IPage<UserPermission> userPermissionsPage = this.baseMapper.selectPage(page, wrapper);
        List<UserPermission> userPermissionsList = userPermissionsPage.getRecords();

        result.put("total", userPermissionsPage.getTotal());
        result.put("currentPage", currentPage);
        result.put("pageSize", pageSize);

        List<User> users = new ArrayList<>();
        List<JoinUserVo> joinUserVos = new ArrayList<>();

        for (UserPermission userPermission : userPermissionsList) {
            User user1 = new User();
            user1 = userService.getUserById(userPermission.getUserId());
            JoinUserVo joinUserVo = new JoinUserVo();
            joinUserVo.setProjectId(getJoinUserVo.getProjectId());
            joinUserVo.setUserId(userPermission.getUserId());
            joinUserVo.setGender(user1.getGender());
            joinUserVo.setUserName(user1.getNickName());
            joinUserVo.setUserPhone(user1.getPhone());
            joinUserVo.setHospitalName(hospitalInformationService.getNameById(user1.getHsId()));
            joinUserVo.setDepartmentName(departmentService.getDepartmentById(user1.getDepartmentId()));
            if (userPermission.getProjectOwnId().equals(userPermission.getUserId())) {
                joinUserVo.setIdentity("创建者");
            } else {
                joinUserVo.setIdentity("成员");
            }
            joinUserVos.add(joinUserVo);
        }
        result.put("result", joinUserVos);
        return result;
    }


    //TODO 进行各个权限的检查,没有权限直接抛出异常
    @Override
    public void getFormPermission(String projectId) {
        User user = tokenSerivce.getUser();
        LambdaQueryWrapper<UserPermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserPermission::getProjectId, projectId)
                .eq(UserPermission::getUserId, user.getId());
        if (!this.baseMapper.selectOne(wrapper).getFormPermission()) {
            throw new MyException(ResultCode.ERROR.getCode(), "用户没有表单业务相关权限");
        }
    }

    @Override
    public void getDataPermission(String projectId) {
        User user = tokenSerivce.getUser();
        LambdaQueryWrapper<UserPermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserPermission::getProjectId, projectId)
                .eq(UserPermission::getUserId, user.getId());
        if (!this.baseMapper.selectOne(wrapper).getDataPermission()) {
            throw new MyException(ResultCode.ERROR.getCode(), "用户没有表单数据业务相关权限");
        }
    }

    @Override
    public void getFollowUpPermission(String projectId) {
        User user = tokenSerivce.getUser();
        LambdaQueryWrapper<UserPermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserPermission::getProjectId, projectId)
                .eq(UserPermission::getUserId, user.getId());
        if (!this.baseMapper.selectOne(wrapper).getFollowUpPermission()) {
            throw new MyException(ResultCode.ERROR.getCode(), "用户没有随访业务相关权限");
        }
    }

    @Override
    public void getPatientPermission(String projectId) {
        User user = tokenSerivce.getUser();
        LambdaQueryWrapper<UserPermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserPermission::getProjectId, projectId)
                .eq(UserPermission::getUserId, user.getId());
        if (!this.baseMapper.selectOne(wrapper).getPatientPermission()) {
            throw new MyException(ResultCode.ERROR.getCode(), "用户没有患者业务相关权限");
        }
    }

    @Override
    public boolean checkRealUser(String id, String projectId) {
        LambdaQueryWrapper<UserPermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserPermission::getProjectOwnId, id)
                .eq(UserPermission::getProjectId, projectId);
        if (this.baseMapper.selectList(wrapper).size() > 0) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public void refuseUser(String projectId, String userId) {
        LambdaQueryWrapper<UserPermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserPermission::getProjectId, projectId)
                .eq(UserPermission::getUserId, userId);
        int delete = this.baseMapper.delete(wrapper);
        if (delete < 1) {
            throw new MyException(ResultCode.ERROR.getCode(), "拒绝用户加入项目失败");
        }

    }

    @Override
    public Map<String, Boolean> getUserPermissions(String projectId, String userId) {
        LambdaQueryWrapper<UserPermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserPermission::getProjectId, projectId)
                .eq(UserPermission::getUserId, userId);
        UserPermission userPermission = this.baseMapper.selectOne(wrapper);
        Map<String, Boolean> map = new HashMap<>();
        map.put("formPermission", userPermission.getFormPermission());
        map.put("dataPermission", userPermission.getDataPermission());
        map.put("followUpPermission", userPermission.getFollowUpPermission());
        map.put("patientPermission", userPermission.getPatientPermission());
        map.put("advicePermission", userPermission.getAdvicePermission());

        return map;
    }

    @Override
    public List<String> getProjectByUserId(String id) {
        LambdaQueryWrapper<UserPermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserPermission::getUserId, id)
                .ne(UserPermission::getProjectOwnId,id);
        List<UserPermission> userPermissions = this.baseMapper.selectList(wrapper);
        List<String> projectIds = new ArrayList<>();
        if (userPermissions.size() > 0) {
            for (UserPermission userPermission : userPermissions) {
                projectIds.add(userPermission.getProjectId());
            }
            return projectIds;
        }
        return projectIds;
    }

    @Override
    public void deleteUserByProjectId(String projectId) {
        LambdaQueryWrapper<UserPermission>wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(UserPermission::getProjectId,projectId);
        int delete = this.baseMapper.delete(wrapper);
        if (delete<1){
            throw new MyException(ResultCode.ERROR.getCode(),"删除用户失败");
        }
    }
}
